#include "include/thread_Pool.h"

ThreadPool& ThreadPool::getInstance()
{
    static ThreadPool instance(std::thread::hardware_concurrency());
    return instance;
}

ThreadPool::ThreadPool(size_t num_threads) {
    if (num_threads == 0)
        num_threads = 4;
    std::cout << "ThreadPool created with " << num_threads << " threads" << std::endl;
    for (size_t i = 0; i < num_threads; i++)
    {
        // emplace_back对比push_back
        // emplace_back直接在容器末尾构造对象，避免了一次拷贝或移动操作
        // push_back需要先构造对象，然后再将其拷贝或移动到容器末尾
        threads_.emplace_back([this] {
            while (1) {
                std::function<void()> task;
                { //互斥锁作用域
                    std::unique_lock<std::mutex> lock(mtx_);
                    // 线程池被停止或者任务队列不为空时，线程等待
                    condition_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
                    // 如果线程池被停止且任务队列为空，线程退出
                    if (stop_ && tasks_.empty()) {
                        return;
                    }
                    // 从任务队列中取出任务
                    task = std::move(tasks_.front());
                    // 从任务队列中移除任务
                    tasks_.pop();
                }
                task();
            }
        });
    }
}

ThreadPool::~ThreadPool() {
    {
        std::unique_lock<std::mutex> lock(mtx_);
        stop_ = true;
    }
    // 通知所有线程执行完毕任务
    condition_.notify_all();
    for (auto &thread : threads_)
    {
        //std::cout << "Thread " << thread.get_id() << " is joined" << std::endl;
        thread.join();
    }
}


